// 日志记录工具

export const LogLevel = {
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3,
} as const;

export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];

interface LogEntry {
  level: LogLevel;
  message: string;
  timestamp: number;
  data?: any;
  stack?: string;
  url?: string;
  userAgent?: string;
}

class Logger {
  private logs: LogEntry[] = [];
  private maxLogs = 1000;
  private logLevel: LogLevel;

  constructor() {
    this.logLevel = import.meta.env.DEV ? LogLevel.DEBUG : LogLevel.WARN;
  }

  private shouldLog(level: LogLevel): boolean {
    return level >= this.logLevel;
  }

  private createLogEntry(
    level: LogLevel,
    message: string,
    data?: any
  ): LogEntry {
    const entry: LogEntry = {
      level,
      message,
      timestamp: Date.now(),
      url: window.location.href,
      userAgent: navigator.userAgent,
    };

    if (data !== undefined) {
      entry.data = data;
    }

    if (level === LogLevel.ERROR && data instanceof Error) {
      entry.stack = data.stack;
    }

    return entry;
  }

  private addLog(entry: LogEntry): void {
    this.logs.push(entry);

    // 保持日志数量在限制内
    if (this.logs.length > this.maxLogs) {
      this.logs.splice(0, this.logs.length - this.maxLogs);
    }

    // 存储到localStorage（仅在开发环境）
    if (import.meta.env.DEV) {
      try {
        const storedLogs = JSON.parse(localStorage.getItem("app_logs") || "[]");
        storedLogs.push(entry);

        // 只保留最近的100条日志
        if (storedLogs.length > 100) {
          storedLogs.splice(0, storedLogs.length - 100);
        }

        localStorage.setItem("app_logs", JSON.stringify(storedLogs));
      } catch (error) {
        console.warn("Failed to store log to localStorage:", error);
      }
    }
  }

  debug(message: string, data?: any): void {
    if (!this.shouldLog(LogLevel.DEBUG)) return;

    const entry = this.createLogEntry(LogLevel.DEBUG, message, data);
    this.addLog(entry);

    if (import.meta.env.DEV) {
      console.debug(`[DEBUG] ${message}`, data);
    }
  }

  info(message: string, data?: any): void {
    if (!this.shouldLog(LogLevel.INFO)) return;

    const entry = this.createLogEntry(LogLevel.INFO, message, data);
    this.addLog(entry);

    if (import.meta.env.DEV) {
      console.info(`[INFO] ${message}`, data);
    }
  }

  warn(message: string, data?: any): void {
    if (!this.shouldLog(LogLevel.WARN)) return;

    const entry = this.createLogEntry(LogLevel.WARN, message, data);
    this.addLog(entry);

    console.warn(`[WARN] ${message}`, data);
  }

  error(message: string, error?: Error | any): void {
    if (!this.shouldLog(LogLevel.ERROR)) return;

    const entry = this.createLogEntry(LogLevel.ERROR, message, error);
    this.addLog(entry);

    console.error(`[ERROR] ${message}`, error);

    // 在生产环境中发送错误到监控服务
    if (import.meta.env.PROD) {
      this.reportError(entry);
    }
  }

  private async reportError(entry: LogEntry): Promise<void> {
    try {
      // 这里应该发送到实际的错误监控服务
      // 例如：Sentry, LogRocket, 或自定义的错误收集服务

      // 示例：发送到自定义错误收集端点
      // await fetch('/api/errors', {
      //   method: 'POST',
      //   headers: { 'Content-Type': 'application/json' },
      //   body: JSON.stringify(entry)
      // });

      console.log("Error reported:", entry);
    } catch (reportError) {
      console.error("Failed to report error:", reportError);
    }
  }

  getLogs(level?: LogLevel): LogEntry[] {
    if (level !== undefined) {
      return this.logs.filter((log) => log.level >= level);
    }
    return [...this.logs];
  }

  clearLogs(): void {
    this.logs = [];
    localStorage.removeItem("app_logs");
  }

  exportLogs(): string {
    return JSON.stringify(this.logs, null, 2);
  }

  setLogLevel(level: LogLevel): void {
    this.logLevel = level;
  }

  // 性能日志
  time(label: string): void {
    if (import.meta.env.DEV) {
      console.time(label);
    }
  }

  timeEnd(label: string): void {
    if (import.meta.env.DEV) {
      console.timeEnd(label);
    }
  }

  // 网络请求日志
  logRequest(method: string, url: string, data?: any): void {
    this.debug(`HTTP ${method} ${url}`, data);
  }

  logResponse(method: string, url: string, status: number, data?: any): void {
    const message = `HTTP ${method} ${url} - ${status}`;

    if (status >= 400) {
      this.error(message, data);
    } else if (status >= 300) {
      this.warn(message, data);
    } else {
      this.debug(message, data);
    }
  }

  // 用户行为日志
  logUserAction(action: string, data?: any): void {
    this.info(`User Action: ${action}`, data);
  }

  // 路由变化日志
  logRouteChange(from: string, to: string): void {
    this.info(`Route Change: ${from} -> ${to}`);
  }
}

// 创建全局日志实例
export const logger = new Logger();

// 捕获全局错误
window.addEventListener("error", (event) => {
  logger.error("Global Error", {
    message: event.message,
    filename: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    error: event.error,
  });
});

// 捕获未处理的Promise拒绝
window.addEventListener("unhandledrejection", (event) => {
  logger.error("Unhandled Promise Rejection", {
    reason: event.reason,
    promise: event.promise,
  });
});

// 导出便捷方法
export const log = {
  debug: (message: string, data?: any) => logger.debug(message, data),
  info: (message: string, data?: any) => logger.info(message, data),
  warn: (message: string, data?: any) => logger.warn(message, data),
  error: (message: string, error?: Error | any) => logger.error(message, error),
  time: (label: string) => logger.time(label),
  timeEnd: (label: string) => logger.timeEnd(label),
  userAction: (action: string, data?: any) =>
    logger.logUserAction(action, data),
  request: (method: string, url: string, data?: any) =>
    logger.logRequest(method, url, data),
  response: (method: string, url: string, status: number, data?: any) =>
    logger.logResponse(method, url, status, data),
};

export default logger;
